#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <omp.h>
#include <sys/timeb.h>
#include "preprocessor.h"

long getmillis() {
    struct timeb mtimebuffer;

    ftime(&mtimebuffer);
    return 1000 * mtimebuffer.time + mtimebuffer.millitm;
}

int main(int argc, char * args[]) {


    int i, j, counter_wordTotal = 0, counter_wordParcial = 0, words_size[46] = {0};
    FILE *pFile;
    node *words = NULL;
    node *words5 = NULL;
    node *words10 = NULL;
    node *words15 = NULL;
    node *words20 = NULL;
    node *words25 = NULL;
    

    node *words2_5 = NULL;
    node *words2_10 = NULL;
    node *words2_15 = NULL;
    node *words2_20 = NULL;
    node *words2_25 = NULL;
    long mtimea;
    long mtimeb;

    words = preProcessor(&counter_wordTotal, words_size, &words5,  &words10,  &words15,  &words20,  &words25);



    printf("\ndepois %d\n", counter_wordTotal);
    pFile = fopen("res_word_3.txt", "w");
    int n, w;
    char c;
    int th_id, flag = 0, porcent = 0;

    mtimeb = getmillis();

#pragma omp parallel private(th_id,i,j)
    {
        node* aux;
        node* aux_tree;
        char chars[28] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
            'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
            'x', 'y', 'z', '{'};
        int r;
        th_id = omp_get_thread_num();

        srand(time(NULL) * th_id);
        chars[27] = '\0';

        while (1) {
            char s[50] = {0};

            if (flag > 10000) {
                srand(time(NULL) * th_id);
                flag = 0;
                r = rand() % 27;

                for (w = 0; w < 27; w++)
                    chars[w] = ((chars[w] - 'a') + r) % 27 + 'a';

            }

            for (i = 1; i <= 100; i++) {
                flag++;

                for (j = 1; j <= i; j++) {

                    n = rand() % 27;
                    c = chars[n];
                    s[j - 1] = c;

                    if (findN(s, words, j) == NULL)
                        j = i;

                    aux = find(s, words5);
                    if (aux != NULL) {
                        if (find(s, words2_5) == NULL) {


                            flag = 0;
                            words2_5 = insert(s, words2_5);

                            #pragma omp critical 
                            while (aux->rowSub != NULL) {
                                aux_tree = findSub(getRowNode(aux), words, 0);
                                if (aux_tree->complete) {
                                    fprintf(pFile, "%s\n", aux_tree->word);

                                    counter_wordParcial++;
                                }

                            }

                            if (porcent != (counter_wordParcial * 100) / counter_wordTotal) {
                                if (porcent % 10 == 0 || porcent == 99) {
                                    mtimea = getmillis();
                                    printf("Tempo de %d é = %d\n", porcent, mtimea - mtimeb);
                                }

                                porcent = (counter_wordParcial * 100) / counter_wordTotal;
//                                 printf("total %d encontrados %d porcentagem %d th_id %d j %d i %d\n", counter_wordTotal, counter_wordParcial,
//                                         (counter_wordParcial * 100) / counter_wordTotal, th_id, j, i);
                            }

                        }
                    }


                    // #pragma omp critical                 
                    aux = find(s, words10);
                    if (aux != NULL) {
                        if (find(s, words2_10) == NULL) {

                            flag = 0;
                            words2_10 = insert(s, words2_10);
                            #pragma omp critical 
                            while (aux->rowSub) {
                                aux_tree = findSub(getRowNode(aux), words, 1);
                                if (aux_tree->complete) {
                                    fprintf(pFile, "%s\n", aux_tree->word);

                                    counter_wordParcial++;
                                }

                            }

                            if (porcent != (counter_wordParcial * 100) / counter_wordTotal) {
                               if (porcent % 10 == 0 || porcent == 99) {
                                    mtimea = getmillis();
                                    printf("Tempo de %d é = %d\n", porcent, mtimea - mtimeb);
                                }
                                porcent = (counter_wordParcial * 100) / counter_wordTotal;
//                                 printf("total %d encontrados %d porcentagem %d th_id %d j %d i %d\n", counter_wordTotal, counter_wordParcial,
//                                         (counter_wordParcial * 100) / counter_wordTotal, th_id, j, i);
                            }

                        }
                    }

                    // #pragma omp critical                 
                    aux = find(s, words15);
                    if (aux != NULL) {
                        if (find(s, words2_15) == NULL) {

                            flag = 0;
                            words2_15 = insert(s, words2_15);
                            #pragma omp critical 
                            while (aux->rowSub) {
                                aux_tree = findSub(getRowNode(aux), words, 2);
                                if (aux_tree->complete) {
                                    fprintf(pFile, "%s\n", aux_tree->word);
                                    counter_wordParcial++;
                                }

                            }

                            if (porcent != (counter_wordParcial * 100) / counter_wordTotal) {
                               if (porcent % 10 == 0 || porcent == 99) {
                                    mtimea = getmillis();
                                    printf("Tempo de %d é = %d\n", porcent, mtimea - mtimeb);
                                }
                                porcent = (counter_wordParcial * 100) / counter_wordTotal;
//                                 printf("total %d encontrados %d porcentagem %d th_id %d j %d i %d\n", counter_wordTotal, counter_wordParcial,
//                                         (counter_wordParcial * 100) / counter_wordTotal, th_id, j, i);
                            }

                        }
                    }

                    aux = find(s, words20);
                    if (aux != NULL) {
                        if (find(s, words2_20) == NULL) {

                            flag = 0;
                            words2_20 = insert(s, words2_20);

                            #pragma omp critical 
                            while (aux->rowSub) {
                                aux_tree = findSub(getRowNode(aux), words, 3);

                                if (aux_tree->complete) {
                                    fprintf(pFile, "%s\n", aux_tree->word);
                                    counter_wordParcial++;
                                }

                            }

                            if (porcent != (counter_wordParcial * 100) / counter_wordTotal) {
                                if (porcent % 10 == 0 || porcent == 99) {
                                    mtimea = getmillis();
                                    printf("Tempo de %d é = %d\n", porcent, mtimea - mtimeb);
                                }
                                porcent = (counter_wordParcial * 100) / counter_wordTotal;
//                                 printf("total %d encontrados %d porcentagem %d th_id %d j %d i %d\n", counter_wordTotal, counter_wordParcial,
//                                         (counter_wordParcial * 100) / counter_wordTotal, th_id, j, i);
                            }

                        }
                    }

                    // #pragma omp critical                 
                    aux = find(s, words25);
                    if (aux != NULL) {
                        if (find(s, words2_25) == NULL) {

                            flag = 0;
                            words2_25 = insert(s, words2_25);

                            #pragma omp critical 
                            while (aux->rowSub) {
                                aux_tree = findSub(getRowNode(aux), words, 4);

                                if (aux_tree->complete) {
                                    fprintf(pFile, "%s\n", aux_tree->word);
                                    counter_wordParcial++;
                                }

                            }

                            if (porcent != (counter_wordParcial * 100) / counter_wordTotal) {
                                if (porcent % 10 == 0) {
                                    mtimea = getmillis();
                                    printf("Tempo de %d é = %d\n", porcent, mtimea - mtimeb);
                                }
                                porcent = (counter_wordParcial * 100) / counter_wordTotal;
//                                 printf("total %d encontrados %d porcentagem %d th_id %d j %d i %d\n", counter_wordTotal, counter_wordParcial,
//                                         (counter_wordParcial * 100) / counter_wordTotal, th_id, j, i);
                            }
                        }
                    }



                    if (counter_wordParcial == counter_wordTotal)
                        exit(0);
                }
            }
        }
    }


    fclose(pFile);
    







    return 0;
}


